﻿#ifndef PLAYER_H
#define PLAYER_H

//#include <QGraphicsItem>
#include "Pai.h"

#include <QObject>
#include <QList>
//#include "_Global/GameGlobal.h"
//#include "Diff.h"
/*
class WuJiangJi
{

};
*/


//玩家
class _Player : public _BaseObject
{
    Q_OBJECT
    Q_ENUMS(JiaoSe)

    Q_PROPERTY(qint32 wuJiangValue READ wuJiangValue)    //武将的id,无则-1
    Q_PROPERTY(int weaponCount READ weaponCount)    //武器数
    Q_PROPERTY(bool dead READ dead WRITE setDead NOTIFY deadChanged)    //死亡

    Q_PROPERTY(QObjectList shouPaiList READ shouPaiList)
    Q_PROPERTY(QObjectList zhuangBeiList READ zhuangBeiList)
    Q_PROPERTY(QObjectList panDingList READ panDingList)
    Q_PROPERTY(QObjectList jiNengList READ jiNengList)
public:

    //玩家类型
    enum JiaoSe {
        JiaoSe_Null = 0,    //没有玩家
        JiaoSe_AI = 1,      //电脑
        JiaoSe_Self = 2,    //玩家
        JiaoSe_Others = 3,  //联机玩家
        JiaoSe_Server = 4,  //服务器
        JiaoSe_Watcher = 5,  //观察者
        //JiaoSe_Auto = 4     //玩家托管
    };


signals:
    void s_SetBlood(qint32 tili, qint32 maxtili);
    void s_RefreshBlood(qint32 blood);
    void s_qml_RefreshWuJiang();
    void s_ShouPaiShu(qint32 count);

    void deadChanged(bool newValue);

    void s_Critical(QString str);


public:
    explicit _Player();
    virtual ~_Player();


public:
    Q_INVOKABLE void setProp(qint32 id = -1)
    {
        _BaseObject::setProp(id, ObjType_Player, Area_Player);
    }
    //初始化
    virtual void init();

    void clearAllWuJiang()
    {
        qDeleteAll(m_listWuJiangQu);
        m_listWuJiangQu.clear();
    }
    //得到武将wuJiangValue,n是放在第几个位置
    int getWuJiang(_WuJiang::_Value wuJiangValue, int n = 0);

    int refreshJiNeng()
    {
        int i = 0;
        //从Player中读取技能
        QList<_Pai*>::const_iterator iiJiNengPai;
        for (iiJiNengPai = m_listPlayerJiNeng.constBegin(); iiJiNengPai != m_listPlayerJiNeng.constEnd(); ++iiJiNengPai)
        {
            _Pai *pJiNeng = (_Pai*)(*iiJiNengPai);
            m_listJiNengPai.append(pJiNeng);

            pJiNeng->setPosition(Area_JiNeng, i, this->id());
            i++;
        }

        //从武将中读取技能
        QList<_WuJiang*>::const_iterator iiWuJiang;
        for (iiWuJiang = m_listWuJiangQu.constBegin(); iiWuJiang != m_listWuJiangQu.constEnd(); ++iiWuJiang)
        {
            _WuJiang *pWuJiang = (_WuJiang*)(*iiWuJiang);

            for (iiJiNengPai = pWuJiang->m_listJiNengPai.constBegin(); iiJiNengPai != pWuJiang->m_listJiNengPai.constEnd(); ++iiJiNengPai)
            {
                _Pai *pJiNeng = (_Pai*)(*iiJiNengPai);
                m_listJiNengPai.append(pJiNeng);

                pJiNeng->setPosition(Area_JiNeng, i, this->id());
                i++;
            }
        }
        return 0;
    }

    void addBlood(int n)
    {
        if(n != 0)
        {
            m_nTiLi += n;
            emit s_RefreshBlood(m_nTiLi);
        }
    }



    //返回 某iType的iPai牌数,错误返回-1
    //iPai:某牌(或所有牌_Pai::Value_All)
    //Type:手牌/判定区/装备
    int getPaiCount(_Pai::_PaiValue pai,_BaseObject::_Area area);        //手牌和判定区的
    int getPaiCount(_BaseObject::_Areas subAreas,_BaseObject::_Area area);   //装备的
    int getPaiCount()       //所有
    {
        return m_listShouPai.count() + m_listPanDing.count() + m_listZhuangBei.count();
    }

    //返回牌的指针
    _Pai*           getShouPaiData(int n);
    _Pai*           getJiNengPaiData(int n);
    _Pai*           getZhuangBeiData(_BaseObject::_Area area);
    _Pai*           getZhuangBeiData(int n);
    _Pai*           getPandingData(int n);
    _WuJiang*       getWujiangData(int n = 0);

    /*
    //返回槽的指针
    GameSlot* GetShouPaiSlot(int n);
    GameSlot* GetZhuangBeiSlot(int n);
    GameSlot* GetPandingSlot(int n);
    GameSlot* GetWujiangSlot(int n);
    */

    //得到一张手牌,返回 手牌数
    //如果出错,返回-2,-3
    //如果手牌满,返回-1
    int getShouPai(_Pai *p);

    //装备装备牌,如果重复装备,返回原装备指针
    _Pai* getZhuangBei(_Pai *p);

    //装备判定牌,成功装上返回1;如果已有返回0
    //出错返回-1,-2
    int getPanDingPai(_Pai *p);

    //是否包含某个装备
    bool containZhuangBei(_Pai::_PaiValue);
    bool containPanDing(_Pai::_PaiValue);

    bool containJiNeng(_JiNeng::_JiNengValue value);

    //删除并返回弃牌指针
    //出错返回NULL
    //bTiaoZheng:是否自动调整牌堆
    _Pai* qiShouPai(int n, bool bTiaoZheng);

    //拿出装备牌,返回指针,没有返回NULL
    _Pai* qiZhuangBei(_Areas areas = Area_ZhuangBei);//_Pai::_PaiType type = _Pai::Type_All);
    //QiPanDing自动调整牌堆
    _Pai* qiPanDing(int n = 0);

    //调整所有牌,返回手牌数
    int tiaoZhengShouPaiDui();
    //int tiaoZhengPanDingQu();

    //根据 手牌的类型iPai 设置m_eFlags,返回设置的数目
    int flagShouPai(_Flags flags, _Pai::_PaiValue, _BaseObject::_FlagType type = _BaseObject::FlagType_Set);

    //根据 装备的iPai来设置m_eFlags,返回设置的数目
    int flagZhuangBeiByValue(_Flags flags, _Pai::_PaiValue pai, _BaseObject::_FlagType type = _BaseObject::FlagType_Set);

    //根据 装备的Area来设置m_eFlags,返回设置的数目
    int flagZhuangBeiByArea(_Flags flags, _BaseObject::_Areas areas, _BaseObject::_FlagType type = _BaseObject::FlagType_Set);

    //根据 判定的iPai来设置m_eFlags,返回设置的数目
    int flagPanDing(_Flags flags, _Pai::_PaiValue, _BaseObject::_FlagType type = _BaseObject::FlagType_Set);

    //根据 手牌的类型iPai 设置m_eFlags,返回设置的数目
    int flagJiNengPai(_Flags flags, _Pai::_PaiValue, _BaseObject::_FlagType type = _BaseObject::FlagType_Set);

    //重置所有类型的牌
    int resetAllFlags()
    {
        if(getWujiangData() == nullptr)return -1;
        setFlags(Flag_Null);
        flagShouPai(Flag_Null,_Pai::Value_All);
        flagZhuangBeiByValue(Flag_Null,_Pai::Value_All);
        flagPanDing(Flag_Null,_Pai::Value_All);
        flagJiNengPai(Flag_Null,_Pai::Value_All);

        return 0;
    }

    bool isMe()
    {
        return (m_eJiaoSe == _Player::JiaoSe_Self);
    }
    bool isComputer()
    {
        return (m_eJiaoSe == _Player::JiaoSe_AI);
    }
    bool isOtherPlayer()
    {
        return (m_eJiaoSe == _Player::JiaoSe_Others);
    }


public:
    //property

    qint32 wuJiangValue() const
    {
        if(m_listWuJiangQu.count() <= 0)return -1;
        else
            return m_listWuJiangQu.at(0)->id();
    }

    QObjectList shouPaiList() const
    {
        return m_listShouPai;
    }
    QObjectList zhuangBeiList() const
    {
        return m_listZhuangBei;
    }
    QObjectList panDingList() const
    {
        return m_listPanDing;
    }
    QObjectList jiNengList() const
    {
        return m_listJiNengPai;
    }

    int weaponCount()
    {
        return getPaiCount(Area_WuQi, Area_ZhuangBei);
    }

    bool dead() const
    {
        return m_bDead;
    }
    void setDead(bool newValue)
    {
        if(m_bDead != newValue)
        {
            m_bDead = newValue;
            emit deadChanged(newValue);
        }
    }



//游戏外部设置:
public:
    QList<_Pai*> m_listPlayerJiNeng;        //网络读取的玩家技能(最终换为m_listJiNengPai)
    //QList<_Pai*> m_listWuJiangJiNeng;       //武将的技能(最终换为m_listJiNengPai)

    JiaoSe      m_eJiaoSe;              //0是AI,1是自己,2是其他玩家
    qint32      m_nDuiWu;               //队伍(-1为无队伍,自己获胜即可)
    QString     m_strName;              //昵称

//游戏中使用数据:
public:
    qint32      m_nJieDuan;           //处于什么阶段(0~5),回合开始~回合结束
    qint32      m_nSha;               //杀的次数

    qint32      m_nTiLi;                //体力
    qint32      m_nTiLiShangXian;       //体力上限

    bool        m_bDead;              //死亡标志

    //qint32      iShenFen;           //1:主公2:忠臣;3:反贼;4:内奸
    bool        m_bTuoGuan;           //玩家是否托管

    int         m_nChuPaiPoint;       //保存 电脑 主动出牌 的 指向


//拥有的物件
public:
    QObjectList m_listShouPai;
    QObjectList m_listZhuangBei;
    QObjectList m_listPanDing;

    QObjectList m_listJiNengPai;    //技能牌

//阶段变量
public:
    int         m_nHuiHeKaiShi;                //回合开始,0正常,-1跳过
    int         m_nPanDingJieDuan;                //判定阶段,0正常
    int         m_nMoPaiJieDuan;                //摸牌阶段,0正常
    int         m_nChuPaiJieDuan;                //出牌阶段,0可以出牌,-1不可以出牌
    int         m_nQiPaiJieDuan;                //弃牌阶段,
    int         m_nHuiHeJieShuJieDuan;            //结束阶段

protected:

private:
    QList<_WuJiang*> m_listWuJiangQu;       //武将列表,目前只有1个

    //int         comIndex;   //暂且没用
    /*
    int huihejieshu;        //回合结束,0正常
    int juese;                            //角色 ID(玩家和电脑),255是电脑,0~100是玩家???
    */
    /*
    union
    {
        _Pai *PaiQu[GAME_MAX_NUM_SLOT_SHOUPAI + GAME_MAX_NUM_SLOT_ZHUANGBEI + GAME_MAX_NUM_SLOT_PANDING];

        struct
        {
            _Pai *ShouPaiQu[GAME_MAX_NUM_SLOT_SHOUPAI];
            _Pai *ZhuangBeiQu[GAME_MAX_NUM_SLOT_ZHUANGBEI];
            _Pai *PanDingQu[GAME_MAX_NUM_SLOT_PANDING];
        };
    };
    */
    //int         ZhuangBeiCount;//,ShouPaiCount,PanDingCount;        //牌数

    //从WuJiang拷贝(可以选同一个武将)
    //    QList<_WuJiang*>    WuJiangList;
    //qint32      WuJiangCount;

//    ObjectInfo    PanDingQu[GAME_MAX_NUM_SLOT_PANDING];    //判定区
    //_BaseObject::_Flags m_eFlags;                                //状态


};

Q_DECLARE_METATYPE(_Player*)

#endif // PLAYER_H
